home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / DSUTIL12 / FILE2BIN / FILE2BIN.PAS < prev   
Pascal/Delphi Source File  |  1993-10-28  |  15KB  |  489 lines

  1. {-----------------------------------------------------------------------}
  2. { PROJECT        NON-PROFIT HIGH QUALITY PROFESSIONAL SOFTWARE,  }
  3. {            AVAILABLE FOR ALL WORLD                }
  4. { LIBRARY        SYSTEM UTILITIES                                }
  5. { MODULE        FILE_TO_BIN_COPY                                }
  6. { FILE NAME        FILE2BIN.PAS                    }
  7. { PURPOSE        Extract the file portion to binary image        }
  8. { VERSION        1.30                        }
  9. { DATE            28-Oct-93                    }
  10. { DESIGN        Dmitry Stefankov                }
  11. { IMPLEMENTATION    Dmitry Stefankov                 }
  12. { COMPANY        Freelance Software Engineer            }
  13. { ADDRESS        Isakowskogo str, 4-2-30                }
  14. {            Moscow, 123181                    }
  15. {            USSR                        }
  16. {            Tel. 007 (095) 944-6304                }
  17. { COPYRIGHT NOTICE    Copyright (C) 1987-1993, Dmitry Stefankov    }
  18. { RESTRICTED RIGHTS    AVAILABLE ONLY FOR FREE DISTRIBUTION,           }
  19. {            NOT FOR COMMERCIAL PURPOSE            }
  20. { COMPUTER        IBM PC or compatible                }
  21. { OPERATING SYSTEM    MS/PC-DOS Version 3.30 or higher        }
  22. { COMPILER        Turbo Pascal Version 6.0            }
  23. {                       (Borland International Inc.) or compatible      }
  24. { ASSEMBLY LANGUAGE    Microsoft MASM 5.10 or compatible               }
  25. { LINKER        Turbo Pascal internal                           }
  26. { ARGUMENTS        <infile>   -  input  stream                     }
  27. {                       <outfile>  -  output stream                     }
  28. {                       <filepos>  -  offset in input file              }
  29. {                       <count>    -  # of bytes to copy                }
  30. { RETURN        None                        }
  31. { REQUIRES        None                                            }
  32. { NATURAL LANGUAGE      English Language                                 }
  33. { SPECIAL        None                        }
  34. { DESCRIPTION        1. Seek <filepos> in input file                 }
  35. {                       2. Copy <count> bytes from input to output      }
  36. { REVISION HISTORY    Dima Stefankov (DS)                }
  37. {               1.00   04-Jan-92  DS  initilal release        }
  38. {                       1.01   05-Jan-92  DS  add documentation         }
  39. {                       1.02   09-Jan-92  DS  some syntax corrections   }
  40. {                       1.03   10-Jan-92  DS  changed r/w algorithms    }
  41. {                       1.04   24-Jan-92  DS  some corrections          }
  42. {            1.10   25-Aug-92  DS  updated documentation    }
  43. {                       1.20   08-Oct-92  DS  some style corrections    }
  44. {                       1.21   27-Oct-92  DS  some corrections          }
  45. {                       1.22   04-Nov-92  DS  some updates              }
  46. {                       1.23   07-Apr-93  DS  some corrections          }
  47. {                       1.24   19-May-93  DS  some style updates        }
  48. {            1.25   04-Jul-93  DS  updated documentation    }
  49. {            1.30   28-Oct-93  DS  some style updates    }
  50. {-----------------------------------------------------------------------}
  51.  
  52.  
  53. {*======================= PROGRAM HEADER PART ==========================*}
  54.  
  55. PROGRAM   ExtractFromFileToBinaryImage;
  56.  
  57.  
  58. {*** other modules ***}
  59. {*USES;*}
  60.  
  61.  
  62. {** switches for compilation **}
  63. {$S-}                {*  stack checking  *}
  64. {$R-}                   {*  range checking  *}
  65. {$M 16384,65536,65536}  {*  memory allocation  *}
  66.  
  67.  
  68. {*========================== CONSTANTS PART ============================*}
  69.  
  70. CONST
  71.  
  72.      asPurpose                  =       'File Smart Copy';
  73.      asVersion                  =       '1.30';
  74.      asAuthor                   =       'Dima Stefankov';
  75.      asCopyright                =       'Copyright (c) 1987, 1993';
  76.      asProgram                  =       'File2bin';
  77.      asProgramPrompt            =       asProgram+': ';
  78.      asProgramU                 =       'FILE2BIN';
  79.  
  80.      { exit codes }
  81.      errTerminateOK             =     0;
  82.      errBadParmsNumber          =     1;
  83.      errSourceNotFound          =     2;
  84.      errDestDontWrite           =     3;
  85.      errBadOffset               =     4;
  86.      errBadSize                 =     5;
  87.      errSrcOpenFailed           =     6;
  88.      errDestCreateFailed        =     7;
  89.      errSeekInSourceFailed      =     8;
  90.      errZeroLengthFound         =     9;
  91.  
  92.      achNULL                    =     #0;
  93.      achCR                      =     #13;
  94.  
  95.      achYes                     =     'Y';
  96.      achNo                      =     'N';
  97.  
  98.      achHexPrefix               =     '$';
  99.      achDosExtMark              =     '.';
  100.      asInDefExt                 =     'exe';
  101.      asOutDefExt                =     'bin';
  102.  
  103.      aPercent100                =     100;
  104.      aHexRadix                  =     16;
  105.      aMaxOnHeap                 =     65520;
  106.  
  107.  
  108. {*==================== TYPE DECLARATIONS PART ==========================*}
  109.  
  110. TYPE
  111.     STR3        =       STRING[3];
  112.  
  113.  
  114. {*====================== TYPED CONSTANTS PART ==========================*}
  115.  
  116. CONST
  117.  
  118.     setHexChars        :  SET OF System.Char  =  ['0'..'9','A'..'F','a'..'f'];
  119.     gddBytesCountDone  :  System.Longint =  0;
  120.  
  121.  
  122. {*=========================== VARIABLES PART ===========================*}
  123.  
  124. VAR
  125.  
  126.    gfInputStream    :   FILE;
  127.    gsInFileName     :   STRING[80];
  128.  
  129.    gfOutputStream   :   FILE;
  130.    gsOutFileName    :   STRING[80];
  131.  
  132.    gddOffsetInFile  :   System.Longint;
  133.    gddByteCount     :   System.Longint;
  134.    gddInFileSize    :   System.Longint;
  135.  
  136.    gdwMemBlockSize  :   System.Word;
  137.    gdwBytesRead     :   System.Word;
  138.    gpMemoryBlock    :   System.Pointer;
  139.  
  140.    giErrorCode      :   System.Integer;
  141.  
  142.    gsTempInput      :   STRING;
  143.    gchInUser        :   System.Char;
  144.  
  145.  
  146. {*=========================== FUNCTIONAL PART ==========================*}
  147.  
  148. FUNCTION  _fndbHexCharToBin(chIn: System.Char) : System.Byte; assembler;
  149. {* Converts the hexadecimal char to decimal. *}
  150. asm
  151.         mov   al, chIn       { AL = chIn }
  152.         sub   al,'0'         { AL <- AL - '0' }
  153.  
  154.         cmp   al,9           { test for digit }
  155.         jbe   @Done
  156.  
  157.         and   al,11011111b   { make uppercase }
  158.         sub   al,'A'-'9'-1   { AL = 'A'..'F' }
  159.  
  160.       @Done:
  161.                         { AL = function result }
  162. END;
  163.   {asm-end}
  164. { HexCharToDec }
  165.  
  166.  
  167. FUNCTION  _fnliHexStrToBin(sHexInput : STRING; VAR iErrCode : System.Integer) : System.Longint;
  168. {* Converts hexadecimal string to decimal number. *}
  169. VAR
  170.   ddNumber               :       System.Longint;
  171.   dbStrIndex, dbStrLen   :       System.Byte;
  172.  
  173. BEGIN
  174.   iErrCode   := 0;
  175.   ddNumber   := 0;
  176.   dbStrIndex := 1;
  177.   dbStrLen   := System.Length(sHexInput);
  178.  
  179.   WHILE (iErrCode = 0) and (dbStrLen > 0) DO
  180.   BEGIN
  181.     IF  (sHexInput[dbStrIndex] IN setHexChars)
  182.     THEN  BEGIN
  183.                ddNumber := ddNumber * aHexRadix + _fndbHexCharToBin(sHexInput[dbStrIndex]);
  184.                System.Inc(dbStrIndex);
  185.                System.Dec(dbStrLen);
  186.           END
  187.     ELSE
  188.         iErrCode  := -1;
  189.     {if-then-else}
  190.   END;
  191.   {while-do}
  192.  
  193.   _fnliHexStrToBin := ddNumber;
  194. END;  { _fnliHexStrToBin }
  195.  
  196.  
  197. FUNCTION  _fnbFileExist(VAR fStruc : FILE; sFileName : STRING) : System.Boolean;
  198. {* Check that file exits. *}
  199. VAR
  200.   bResult  :  System.Boolean;
  201.  
  202. BEGIN
  203.   {** try to open the file **}
  204.   System.Assign(fStruc,sFileName);
  205.   {$I-}
  206.   System.Reset(fStruc);
  207.   {$I+}
  208.  
  209.   {** copy the result of last I/O operation **}
  210.   bResult := (System.IOResult = 0);
  211.  
  212.   IF (bResult)
  213.     THEN  System.Close(fStruc);
  214.   {if-then}
  215.  
  216.   _fnbFileExist := bResult;
  217. END; { _fnbFileExist }
  218.  
  219.  
  220. FUNCTION  _fnsForceFileNameExt(sFileName, sDefExt : STRING) : STRING;
  221. {* Add extension for filename if not present. *}
  222. BEGIN
  223.    IF (System.Pos(achDosExtMark,sFileName) = 0)
  224.      THEN  sFileName := sFileName + achDosExtMark + sDefExt;
  225.    {if-then}
  226.   _fnsForceFileNameExt := sFileName;
  227. END;
  228. { _fnsForceFileNameExt }
  229.  
  230.  
  231. FUNCTION  _fnsUpcaseStr(sInput : STRING) : STRING;
  232. {* Make all uppercase. *}
  233. VAR
  234.   dbIndex  :  System.BYTE;
  235.   dbCount  :  System.BYTE;
  236.  
  237. BEGIN
  238.   dbCount := System.Length(sInput);
  239.  
  240.   IF (dbCount <> 0)  THEN
  241.     FOR dbIndex :=  1  TO  dbCount DO
  242.       sInput[dbIndex] := System.Upcase(sInput[dbIndex]);
  243.     {for-to-do}
  244.   {if-then}
  245.  
  246.    _fnsUpcaseStr := sInput;
  247. END; { _fnsUpcaseStr }
  248.  
  249.  
  250. FUNCTION  _fnddGetNum(sInput : STRING;VAR iErrorCode : System.Integer)  :  System.Longint;
  251. {* Reads a numeric string. *}
  252. VAR
  253.   ddTemp      :   System.Longint;
  254.  
  255. BEGIN
  256.   IF  (sInput[1] <> achHexPrefix)
  257.      THEN  System.Val(sInput,ddTemp,iErrorCode)
  258.      ELSE  ddTemp := _fnliHexStrToBin(Copy(sInput,2,System.Length(sInput)-1),iErrorCode);
  259.   {if-then-else}
  260.   _fnddGetNum := ddTemp;
  261. END;
  262. { _fnddGetNum }
  263.  
  264.  
  265. FUNCTION   _fnchGetFirstChar(sInput : STRING) : System.Char;
  266. {* Returns a first char from string. *}
  267. VAR
  268.   chTemp  :  System.Char;
  269.  
  270. BEGIN
  271.    IF (System.Length(sInput) <> 0)
  272.      THEN  chTemp := sInput[1]
  273.      ELSE  chTemp := achNULL;
  274.    {if-then-else}
  275.   _fnchGetFirstChar := chTemp;
  276. END;
  277. { _fnchGetFirstChar }
  278.  
  279.  
  280. FUNCTION  _fnsNumToStr3(dwNum : System.Word) : STR3;
  281. {* Convert a numeric value to its string representation. *}
  282. VAR
  283.   sTemp : STR3;
  284.  
  285. BEGIN
  286.    System.Str(dwNum:3,sTemp);
  287.    _fnsNumToStr3 := sTemp;
  288. END;
  289. { _fnsNumToStr3 }
  290.  
  291.  
  292.  
  293. {*=========================== PROCEDURAL PART ==========================*}
  294.  
  295. PROCEDURE    _CopyrightDisplay;
  296. {* Outputs the copyright notice. *}
  297. BEGIN
  298.      System.WriteLn(asPurpose+'  Version '+asVersion+',  '+asCopyright+'  '+asAuthor);
  299. END;  { _CopyrightDisplay }
  300.  
  301.  
  302. {*============================== MAIN PART =============================*}
  303.  
  304. BEGIN
  305.   _CopyrightDisplay;
  306.  
  307.      IF (System.ParamCount <> 4) THEN
  308.      BEGIN
  309.           System.WriteLn(asProgramPrompt+'  screen help for you.');
  310.           System.WriteLn('Usage: infile outfile offset size');
  311.           System.WriteLn('  infile   -  source filename      (def. ext. = '+asInDefExt+')');
  312.           System.WriteLn('  outfile  -  destination filename (def. ext. = '+asOutDefExt+')');
  313.           System.WriteLn('  offset   -  offset in source');
  314.           System.WriteLn('  size     -  number of bytes to transfer');
  315.           System.WriteLn('  Numbers may be decimals, or hexadecimals (first symbol is ''$'' for hex.).');
  316.           System.Halt(errBadParmsNumber);
  317.      END; { if }
  318.  
  319.  
  320.   {** copy the parameters from command line **}
  321.   gsInFileName  := _fnsUpcaseStr(System.ParamStr(1));
  322.   gsInFileName := _fnsForceFileNameExt(gsInFileName,asInDefExt);
  323.  
  324.   gsOutFileName := _fnsUpcaseStr(System.ParamStr(2));
  325.   gsOutFileName := _fnsForceFileNameExt(gsOutFileName,asOutDefExt);
  326.  
  327.  
  328.   {** source file exists? **}
  329.   IF  NOT(_fnbFileExist(gfInputStream,gsInFileName)) THEN
  330.   BEGIN
  331.     System.WriteLn(asProgramPrompt+'Unable to open file '+gsInFileName);
  332.     System.Halt(errSourceNotFound);
  333.   END;
  334.   {if-then}
  335.  
  336.  
  337.   {** destination file present? **}
  338.   IF (_fnbFileExist(gfOutputStream,gsOutFileName)) THEN
  339.   BEGIN
  340.     System.Write(asProgramPrompt+'Output file '+gsOutFileName+
  341.                  ' already exists. Overwrite? (n/y): ');
  342.     System.ReadLn(gsTempInput);
  343.     IF (System.UpCase(_fnchGetFirstChar(gsTempInput)) <> achYes)
  344.       THEN  System.Halt(errDestDontWrite);
  345.     {if-then}
  346.   END;
  347.   {if-then}
  348.  
  349.  
  350.   {** read the following parameter = offset **}
  351.   gsTempInput := System.ParamStr(3);
  352.   gddOffsetInFile := _fnddGetNum(gsTempInput,giErrorCode);
  353.  
  354.   IF  (giErrorCode <> 0)  THEN
  355.       BEGIN
  356.         System.WriteLn(asProgramPrompt+'Bad offset parameter.');
  357.         System.Halt(errBadOffset);
  358.       END;
  359.   {if-then}
  360.  
  361.  
  362.   {** read the following parameter = size **}
  363.   gsTempInput  := System.ParamStr(4);
  364.   gddByteCount := _fnddGetNum(gsTempInput,giErrorCode);
  365.  
  366.   IF  (giErrorCode <> 0)  THEN
  367.       BEGIN
  368.         System.WriteLn(asProgramPrompt+'Bad size parameter.');
  369.         System.Halt(errBadSize);
  370.       END;
  371.   {if-then}
  372.  
  373.  
  374.  
  375.   {** open the source file **}
  376.   System.Assign(gfInputStream,gsInFileName);
  377.   {$I-}
  378.   System.Reset(gfInputStream,1);
  379.   {$I+}
  380.  
  381.   IF  (System.IoResult <> 0) THEN
  382.   BEGIN
  383.     System.WriteLn(asProgramPrompt+'Unable to open '+gsInFileName);
  384.     System.Halt(errSrcOpenFailed);
  385.   END;
  386.   {if-then}
  387.  
  388.  
  389.   {** find the wanted # of bytes **}
  390.   IF  (System.FileSize(gfInputStream) < (gddOffsetInFile + gddByteCount))
  391.     THEN  BEGIN
  392.       gddByteCount := System.FileSize(gfInputStream) - gddOffsetInFile;
  393.       System.WriteLn(asProgramPrompt+'Warning! Only partial copy...');
  394.           END;
  395.   {if-then}
  396.  
  397.   IF  (gddByteCount = 0) THEN
  398.   BEGIN
  399.     System.Close(gfInputStream);
  400.     System.WriteLn(asProgramPrompt+'Zero found for bytes count.');
  401.     System.Halt(errZeroLengthFound);
  402.   END;
  403.   {if-then}
  404.  
  405.  
  406.   {** seek wanted position in file. **}
  407.   IF  (System.FileSize(gfInputStream) <= gddOffsetInFile) THEN
  408.   BEGIN
  409.     System.Close(gfInputStream);
  410.     System.WriteLn(asProgramPrompt+'Seek operation in source file failed.');
  411.     System.Halt(errSeekInSourceFailed);
  412.   END;
  413.   {if-then}
  414.  
  415.   {$I-}
  416.   System.Seek(gfInputStream,gddOffsetInFile);
  417.   {$I+}
  418.  
  419.  
  420.  
  421.   {** create the destination file **}
  422.   System.Assign(gfOutputStream,gsOutFileName);
  423.   {$I-}
  424.   System.Rewrite(gfOutputStream,1);
  425.   {$I+}
  426.  
  427.   IF  (System.IoResult <> 0) THEN
  428.   BEGIN
  429.     System.Close(gfInputStream);
  430.     System.WriteLn(asProgramPrompt+'Unable to create '+gsOutFileName);
  431.     System.Halt(errDestCreateFailed);
  432.   END;
  433.   {if-then}
  434.  
  435.  
  436.  
  437.   {** get memory on heap **}
  438.   IF  (System.MaxAvail < aMaxOnHeap)
  439.     THEN  gdwMemBlockSize := System.MaxAvail
  440.     ELSE  gdwMemBlockSize := aMaxOnHeap;
  441.   {if-then-else}
  442.   System.GetMem(gpMemoryBlock,gdwMemBlockSize);
  443.   gddInFileSize := gddByteCount;
  444.  
  445.  
  446.  
  447.  
  448.   {** simple algorithm for buffered copy **}
  449.   WHILE (gddByteCount <> 0) DO
  450.   BEGIN
  451.        IF  ((gddByteCount DIV gdwMemBlockSize) <> 0)
  452.           THEN  gdwBytesRead := gdwMemBlockSize
  453.           ELSE gdwBytesRead := gddByteCount;
  454.        {if-then-else}
  455.        System.Inc(gddBytesCountDone,gdwBytesRead);
  456.  
  457.                System.WriteLn(asProgramPrompt+'Reading...');
  458.                System.BlockRead(gfInputStream,
  459.                                 System.Mem[System.Seg(gpMemoryBlock^):System.Ofs(gpMemoryBlock^)],
  460.                                 gdwBytesRead,
  461.                                 gdwBytesRead);
  462.                System.WriteLn(asProgramPrompt+'Writing...');
  463.                System.BlockWrite(gfOutputStream,
  464.                                  System.Mem[System.Seg(gpMemoryBlock^):System.Ofs(gpMemoryBlock^)],
  465.                                  gdwBytesRead);
  466.                System.Dec(gddByteCount,gdwBytesRead);
  467.                System.Write(achCR+asProgramPrompt+'Completed ('+
  468.                _fnsNumToStr3((gddBytesCountDone*aPercent100) DIV gddInFileSize)+'%)');
  469.                System.WriteLn;
  470.   END;
  471.   {while-do}
  472.  
  473.  
  474.   {** free memory on heap **}
  475.   System.FreeMem(gpMemoryBlock,gdwMemBlockSize);
  476.  
  477.  
  478.   {** close all files **}
  479.   System.Close(gfInputStream);
  480.   System.Close(gfOutputStream);
  481.  
  482.  
  483.   {** report all done **}
  484.   System.WriteLn(asProgramPrompt+'Done.');
  485.  
  486.   {* System.Halt(errTerminateOk); *}
  487. END.
  488.  
  489.